import { useState, useRef } from "react";
import { invoke } from "@tauri-apps/api/core";
import { useNavigate, useLocation } from "react-router-dom";
import { confirm, open, save } from "@tauri-apps/plugin-dialog";
import { basename } from '@tauri-apps/api/path';
import { UserInterface, FileItem, amountOfStatus } from "./UserInterface.tsx";
import OSS from 'ali-oss';

export function ExplorerFunctions() {
    const [currentPath, setCurrentPath] = useState("");
    const [files, setFiles] = useState<FileItem[]>([]);
    const [error, setError] = useState("");
    const [isLoading, setIsLoading] = useState(false);
    const [selectedFiles, setSelectedFiles] = useState<Set<string>>(new Set());
    const [uploadStatus, setUploadStatus] = useState("");
    const [isUploading, setIsUploading] = useState(false);
    const [uploadedFiles, setUploadedFiles] = useState<Set<string>>(new Set());
    const [uploadedFileItems, setUploadedFileItems] = useState<FileItem[]>([]);
    const [logInStatus, setLogInStatus] = useState("");

    const {
        routeInfo,
        ossAccess, 
        mongoDBUrl
    } = UserInterface();
    const routeinforef = useRef(routeInfo);

    const navigate = useNavigate();
    const location = useLocation();
    
    const loadDirectory = async (path: string) => {
        try {
            // setIsLoading(true);
            setError("");
            const files = await invoke<FileItem[]>("list_directory", { path });
            setFiles(files);
            // setIsLoading(false);
            setUploadStatus("");
        } catch (error) {
            console.error("Failed to list directory:", error);
            setError(String(error));
        } finally {
            setIsLoading(false);
        }
    };

    // OSS 客户端配置
    const client = new OSS({
        region: ossAccess?.region || import.meta.env.VITE_OSS_REGION,
        accessKeyId: ossAccess?.oss_access_id 
        || import.meta.env.VITE_OSS_ACCESS_KEY_ID,
        accessKeySecret: ossAccess?.oss_key_secret
        || import.meta.env.VITE_OSS_ACCESS_KEY_SECRET,
        bucket : ossAccess?.bucket || import.meta.env.VITE_OSS_BUCKET,
        secure: true // 使用 HTTPS
    });

    // 对于选中的每个文件的上传
    const uploadEachFile = async ( filePath: string,
        numstruct: amountOfStatus
     )=> {
        try {
            // 获取文件名
            const fileName = await basename(filePath);
            
            const fileContent = await invoke<Uint8Array>("read_file_bytes", { 
                path: filePath 
            });
            // // 上传到 OSS
            // setUploadStatus(`Uploading ${fileName}...`);
            const bytes = new Uint8Array(fileContent);
            const file = new File([bytes], fileName, {
                type: 'application/octet-stream'
            });
            const response = await client.put(fileName, file);
            if (response.res.status === 200) {
                numstruct.successCount++;
                // 保存路径到数据库
                try {
                    await invoke("save_cloud_path", {
                        user : location.state.routeInfo.user,
                        mongodbUrl : location.state.routeInfo.url,
                        filePath : filePath 
                    });
                } catch (err) {
                    console.error("failed upload:", err);
                }
                setUploadStatus(`Uploaded ${numstruct.successCount} of ${selectedFiles.size} file(s)`);
                // setCurrentPathUploadedFiles((prev: Set<string>) => new Set(prev).add(filePath));
                console.log('seccussed upload');
            }
        } catch (err) {
            console.error('Upload failed:', err);
            numstruct.failCount++;
            setUploadStatus(`Failed to upload ${numstruct.failCount} file(s)`);
        }// 上传完成后显示结果
        if (numstruct.failCount === 0) {
        setUploadStatus(`Successfully uploaded ${numstruct.successCount} file(s)`);
        } else {
        setUploadStatus(`Uploaded ${numstruct.successCount} file(s),
             failed to upload ${numstruct.failCount} file(s)`);
        }
    }
    
    // 上传文件到 OSS
    const uploadToOSS = async () => {
        setIsUploading(true);
        try {
            let numstruct: amountOfStatus = { successCount: 0, failCount: 0 };
            if(selectedFiles.size === 0){
                const selected = await open({
                    directory: false,
                    multiple: true,
                    title: "Select Files"
                });
                if(selected){
                    setUploadStatus(`Preparing to upload ${selected.length} file(s)...`);
                    for(const selectfile of selected) uploadEachFile(selectfile, numstruct);
                }
            } else {
                setUploadStatus(`Preparing to upload ${selectedFiles.size} file(s)...`);
                for (const filePath of selectedFiles) uploadEachFile(filePath, numstruct);
            } 
        }catch (error) {
            console.error('Upload process error:', error);
            setError(`Upload process error: ${error}`);
        } finally {
            setIsUploading(false);
        }
    };

    const ifTextFile = (fileName: string)=> {
        const fileExtension = fileName.split('.').pop()?.toLowerCase();
        const textFileExtensions = 
        [
            'txt', 
            'md', 
            'json', 
            'js', 
            'ts', 
            'html', 
            'css', 
            'xml', 
            'csv'
        ];
        return textFileExtensions.includes(fileExtension || '');
    }

    const downLoadEachFile = async (filePath: string, 
        numstruct: amountOfStatus) => {
        try {
                const fileName = await basename(filePath);
                const savePath = await save({
                    defaultPath: filePath,
                    title: "Download File"
                });
                const result = await client.get(fileName);
                // const stream = result.content; // 获取可读流

                const fileContent = new Uint8Array(result.content as ArrayBuffer);
                // 弹出保存对话框
                if (savePath) {
                    if(ifTextFile(fileName)){
                        await invoke("write_text_file", {
                            path: savePath,
                            contents: fileContent
                        });
                    } else{
                        await invoke("write_file_bytes", {
                            path: savePath,
                            contents: fileContent
                        });
                    }
                    numstruct.successCount++;
                    console.log("save path", savePath);
                }
            } catch (err) {
                console.error('Download failed:', err);
                setError(`Download failed: ${err}`);
                numstruct.failCount++;
            }
    }
    
    // 下载云端文件到本地
    const downloadFromOSS = async () => {
        try {
            const confirmed = await confirm(`Download ${selectedFiles.size} file(s) from cloud?`);
            if (!confirmed) return;
            let numstruct: amountOfStatus = { successCount: 0, failCount: 0 };
            for (const filePath of selectedFiles) downLoadEachFile(filePath, numstruct);
            setUploadStatus(
            `Downloaded ${numstruct.successCount} file(s),
            failed: ${numstruct.failCount}`
            );
        } catch (error) {
            console.error('Download process error:', error);
            setError(`Download error: ${error}`);
        }
    };
    
    const deleteEachFile = async(filePath: string, numstruct: amountOfStatus) => {
        try {
            const fileName = await basename(filePath);
            const result = await client.delete(fileName);
            if(result.res.status === 204){
                console.log("delete file", fileName);
                try {
                    await invoke('delete_cloud_path', { 
                        user: routeinforef.current?.user,
                        mongodbUrl : routeinforef.current?.url,
                        filePath : filePath 
                    });
                    setUploadedFileItems(prev => 
                        prev.filter(item => !selectedFiles.has(item.path))
                    );
                    numstruct.successCount++;
                    setUploadedFiles(
                        prev => {
                            const newSet = new Set(prev);
                            newSet.delete(filePath);
                            return newSet;
                        }
                    );
                    // 排除已删除的云端文件项以更新云端文件列表
                    console.log('seccussful deleted', fileName);
                } catch (err) {
                    console.log("Failed delete path:", err);
                }
            }else{
                numstruct.failCount++;
                console.error('Delete failed: ', result.res.status);
            }
        } catch (err) {
            console.error('Delete failed:', err);
            numstruct.failCount++;
        }
    }

    // 添加删除云端文件的方法
    const deleteFromOSS = async () => {
        try {
            let numstruct: amountOfStatus = { successCount: 0, failCount: 0 };
            const confirmed = await confirm(`Delete ${selectedFiles.size} file(s) from cloud?`);
            if (!confirmed) return;
            setIsLoading(true);
            for (const filePath of selectedFiles) {
                deleteEachFile(filePath, numstruct);
            }
            setUploadStatus(
                `Deleted ${numstruct.successCount} file(s) from cloud, failed: ${numstruct.failCount}`
            );
            setIsLoading(false);
            setSelectedFiles(new Set()); // 清空选中的文件
        } catch (error) {
            console.error('Delete process error:', error);
            setError(`Delete error: ${error}`);
        }
    };


    // 处理复选框变化
    const handleCheckboxChange = 
    (event: React.ChangeEvent<HTMLInputElement>, filePath: string) => {
        event.stopPropagation(); // 阻止事件冒泡，防止触发行点击事件
        setSelectedFiles(prev => {
            const newSet = new Set(prev);
            // console.log(event.target.checked);
            event.target.checked ? newSet.add(filePath) : newSet.delete(filePath);
            return newSet;
        });
    };

    // 处理行单击事件 - 只选中行，不执行操作
    const handleRowClick = (file: FileItem) => {
        if(!file.is_dir){
            setSelectedFiles(prev => {
                const newSet = new Set(prev);
                if(prev.has(file.path)){
                    newSet.delete(file.path);
                }  
                else{
                    newSet.add(file.path);
                    console.log("select", file.name);
                } 
                return newSet;
            })
        }
    };

    //  const ifText = (fileName: string)=> {
    //     const fileExtension = fileName.split('.').pop()?.toLowerCase();
    //     const textFileExtensions = 
    //     [
    //         'txt', 
    //         'md', 
    //         'qmd',
    //         'json', 
    //         'js', 
    //         'ts', 
    //         'html', 
    //         'css', 
    //         'xml', 
    //         'csv'
    //     ];
    //     return textFileExtensions.includes(fileExtension || '');
    // }
    // 处理行双击事件 - 执行操作（打开文件或导航到目录）
    const handleRowDoubleClick = async (file: FileItem) => {
        if (file.is_dir) {
            // 如果是目录，导航到该目录
            setCurrentPath(file.path);
        } else {
            // 如果是文本文件，打开文本编辑器
            if (ifTextFile(file.name)) {
                navigate('/editor', { 
                    state: { 
                        filePath: file.path, 
                        name: file.name,
                        path: currentPath,
                        routeInfo : routeinforef.current
                    } 
                });
            }
            else {
            // 如果不是文本文件，尝试用系统默认程序打开
                try {
                    await invoke("open_file", { path: file.path });
                } catch (error) {
                    console.error("Failed to open file:", error);
                    setError(String(error));
                }
            }
        }
    };

    const handleDeleteFiles = async () => {
        const confirmed = await confirm(
            `Are you sure you want to delete ${selectedFiles.size} selected file(s)?`
        );
        if (confirmed) {
            try {
            for (const filePath of selectedFiles) {
                await invoke("delete_file", { path: filePath });
            }
            // 刷新目录
            loadDirectory(currentPath);
            // 清空选中的文件
            setSelectedFiles(new Set());
            } catch (error) {
                console.error("Failed to delete files:", error);
                setError(String(error));
            }
        }
    };
    // 处理删除账户按钮点击
    const handleDeleteAccount = async () => {
        console.log("Delete account button clicked"); // 添加调试日志
        // 显示确认对话框
        const confirmed = await confirm('This action cannot be reverted. Are you sure?', 
            { title: 'Tauri', kind: 'warning' }
        );
        // 如果用户确认，执行删除账户操作
        if (confirmed) {
            try {
            // 调用后端删除当前账户
            const result = await invoke("delete_account",
                 { mongodb_url : mongoDBUrl });
            console.log("Account deletion result:", result);
            // 删除成功后，重定向到登录页面
            navigate("/");
            } catch (error) {
            console.error("Failed to delete account:", error);
            setError(String(error));
            }
        }
    };

    const navigateUp = () => {
        const parentPath = currentPath.split(/[/\\]/).slice(0, -1).join("/");
        if (parentPath) {
            setCurrentPath(parentPath);
        }
    };

    const formatFileSize = (bytes: number): string => {
        if (bytes === 0) return "0 Bytes";

        const k = 1024;
        const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
        const i = Math.floor(Math.log(bytes) / Math.log(k));

        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
    };

    const navigateToSpecialDir = async (dirFunc: () => Promise<string>) => {
        try {
            const path = await dirFunc();
            setCurrentPath(path);
            // checkcloudfiles();
        } catch (error) {
            console.error("Failed to navigate to directory:", error);
            setError(String(error));
        }
    };

    // 选择文件夹的函数
    const handleSelectFolder = async () => {
        try {
            // 打开文件夹选择对话框
            const selected = await open({
                directory: true,
                multiple: false,
                title: "Select Folder"
            });
            // 如果用户选择了文件夹
            if (selected){
                if(!Array.isArray(selected)) {
                    setCurrentPath(selected);
                }
            }
        } catch (error) {
            console.error("Failed to select folder:", error);
            setError(String(error));
        }
    };

    return{
        routeinforef,
        location,
        uploadedFileItems, setUploadedFileItems,
        uploadedFiles,
        files, setFiles,
        error,setError,
        isLoading,
        selectedFiles,setSelectedFiles,
        // uploadFiles, setUploadFiles,
        currentPath,setCurrentPath,
        isUploading, setIsLoading,
        uploadStatus,setUploadStatus,
        logInStatus, setLogInStatus,
        loadDirectory,
        uploadToOSS,
        downloadFromOSS,
        deleteFromOSS,
        handleCheckboxChange,
        handleRowClick,
        handleRowDoubleClick,
        handleDeleteAccount,
        handleDeleteFiles,
        navigateUp,
        handleSelectFolder,
        formatFileSize,
        navigateToSpecialDir,
    }
}